package com.cxq.boot.service;

import com.cxq.boot.dto.PaginationDTO;
import com.cxq.boot.dto.QuestionDTO;
import com.cxq.boot.dto.QuestionQueryDTO;
import com.cxq.boot.exception.CustomizeErrorCode;
import com.cxq.boot.exception.CustomizeException;
import com.cxq.boot.mapper.QuestionExtMapper;
import com.cxq.boot.mapper.QuestionMapper;
import com.cxq.boot.mapper.UserMapper;
import com.cxq.boot.model.Question;
import com.cxq.boot.model.QuestionExample;
import com.cxq.boot.model.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * service层用于访问多种数据实体 (如 UserMapper、QuestionMapper)，起到组装的作用 (又称中间层)
 */
@Service
public class QuestionService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private QuestionExtMapper questionExtMapper;

    /**
     * 所有展示
     */
    public PaginationDTO list(Integer page, Integer size,String search,String tag) {

        //判断是否有搜索
        if (StringUtils.isNotBlank(search)){
            String[] searchs = StringUtils.split(search, " ");
            search = Arrays.stream(searchs).collect(Collectors.joining("|"));
        }

        //设置分页
        PaginationDTO<QuestionDTO> paginationDTO = new PaginationDTO();//分页

        //换成添加了查找方式
        QuestionQueryDTO questionQueryDTO = new QuestionQueryDTO();
        questionQueryDTO.setSearch(search);
        questionQueryDTO.setTag(tag);
        Integer totalCount = questionExtMapper.countBySearch(questionQueryDTO);
        //Integer totalCount = (int) questionMapper.countByExample(new QuestionExample());
        //Integer totalCount = questionMapper.count();//问题总数

        Integer totalPage;
        if (totalCount % size == 0) {
            totalPage = totalCount / size;
        } else {
            totalPage = totalCount / size + 1;
        }

        //设置page
        if (page < 1) {
            page = 1;
        }
        if (page > totalPage) {
            page = totalPage;
        }

        paginationDTO.setPagination(totalPage, page);

        //设置分页问题信息
        Integer offset = size * (page - 1);
        List<QuestionDTO> questionDTOS = new ArrayList<>();

        //改用可能待用查询的方式
        questionQueryDTO.setPage(offset);
        questionQueryDTO.setSize(size);
        List<Question> questions = questionExtMapper.selectBySearch(questionQueryDTO);
        /*QuestionExample example = new QuestionExample();
        example.setOrderByClause("gmt_Create desc");
        List<Question> questions = questionMapper.selectByExampleWithRowbounds(example, new RowBounds(offset, size));*/
        //List<Question> questions = questionMapper.list(offset, size);

        for (Question question : questions) {

            /*UserExample userExample = new UserExample();
            userExample.createCriteria()
                    .andIdEqualTo(question.getCreator());
            List<User> users = userMapper.selectByExample(userExample);
            User user = users.get(0);*/
            User user = userMapper.selectByPrimaryKey(question.getCreator());
            //User user = userMapper.findById(question.getCreator());

            QuestionDTO questionDTO = new QuestionDTO();
            //BeanUtils.copyProperties作用：将源对象属性值复制到目的对象属性
            BeanUtils.copyProperties(question, questionDTO);
            questionDTO.setUser(user);
            questionDTOS.add(questionDTO);
        }
        paginationDTO.setData(questionDTOS);
        return paginationDTO;
    }

    /**
     * 根据用户Id展示我的问题
     * @return
     */
    public PaginationDTO listByUserId(Long userId, Integer page, Integer size) {
        PaginationDTO<QuestionDTO> paginationDTO = new PaginationDTO();//分页

        QuestionExample example = new QuestionExample();
        example.createCriteria()
                .andCreatorEqualTo(userId);
        Integer totalCount = (int) questionMapper.countByExample(example);
        //Integer totalCount = questionMapper.countByUserId(userId);//问题总数

        Integer totalPage;
        if (totalCount % size == 0) {
            totalPage = totalCount / size;
        } else {
            totalPage = totalCount / size + 1;
        }

        //设置page
        if (page < 1) {
            page = 1;
        }
        if (page > totalPage) {
            page = totalPage;
        }

        paginationDTO.setPagination(totalPage, page);

        Integer offset = size * (page - 1);
        List<QuestionDTO> questionDTOS = new ArrayList<>();

        QuestionExample questionExample = new QuestionExample();
        questionExample.createCriteria()
                .andCreatorEqualTo(userId);
        questionExample.setOrderByClause("gmt_create desc");
        List<Question> questions = questionMapper.selectByExampleWithRowbounds(questionExample, new RowBounds(offset, size));
        //List<Question> questions = questionMapper.listByUserId(userId, offset, size);

        for (Question question : questions) {

            User user = userMapper.selectByPrimaryKey(question.getCreator());
            //User user = userMapper.findById(question.getCreator());

            QuestionDTO questionDTO = new QuestionDTO();
            //BeanUtils.copyProperties作用：将源对象属性值复制到目的对象属性
            BeanUtils.copyProperties(question, questionDTO);
            questionDTO.setUser(user);
            questionDTOS.add(questionDTO);
        }
        paginationDTO.setData(questionDTOS);
        return paginationDTO;
    }

    public QuestionDTO getById(Long id) {

        Question question = questionMapper.selectByPrimaryKey(id);
        //Question question = questionMapper.getById(id);

        //设置异常
        if (question == null){
            throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
        }

        QuestionDTO questionDTO = new QuestionDTO();
        BeanUtils.copyProperties(question, questionDTO);

        User user = userMapper.selectByPrimaryKey(question.getCreator());
        //User user = userMapper.findById(question.getCreator());

        questionDTO.setUser(user);
        return questionDTO;
    }

    /**
     * 添加或修改问题
     * @param question
     */
    public void createOrUpdate(Question question) {

        Question dbQuestion = questionMapper.selectByPrimaryKey(question.getId());
        //Question dbQuestion = questionMapper.getById(question.getId());

        if (dbQuestion == null) {
            question.setGmtCreate(System.currentTimeMillis());
            question.setGmtModified(question.getGmtCreate());
            question.setCommentCount(0);//设置默认值（如果数据库为设置默认值时）

            questionMapper.insert(question);
            //questionMapper.create(question);
        } else {
            Question updateQuestion = new Question();
            updateQuestion.setGmtModified(System.currentTimeMillis());
            updateQuestion.setTitle(question.getTitle());
            updateQuestion.setDescription(question.getDescription());
            updateQuestion.setTag(question.getTag());

            QuestionExample example = new QuestionExample();
            example.createCriteria()
                    .andIdEqualTo(dbQuestion.getId());
            int updateId = questionMapper.updateByExampleSelective(updateQuestion, example);
            //questionMapper.update(question);

            if (updateId != 1){
                throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
            }
        }
    }

    //增加阅读数
    public void incview(Long id) {
        //这种方式会出现浏览次数差异问题
        /*Question question = questionMapper.selectByPrimaryKey(id);
        Question updateQuestion = new Question();
        updateQuestion.setViewCount(question.getViewCount() + 1);//设置question浏览数
        QuestionExample example = new QuestionExample();
        example.createCriteria()
                .andIdEqualTo(question.getId());//查找此id的question进行更新
        questionMapper.updateByExampleSelective(updateQuestion, example);*///对question的浏览数更新值，其他值没有设置不会更新
        Question question = new Question();
        question.setId(id);
        question.setViewCount(1);
        questionExtMapper.incview(question);
    }

    //通过标签获取相关问题
    public List<QuestionDTO> selectRelated(QuestionDTO queryQuestion) {
        if (StringUtils.isBlank(queryQuestion.getTag())){
            return new ArrayList<>();
        }

        //获取当前问题所有标签
        String[] tags = StringUtils.split(queryQuestion.getTag(), ",");
        //拼接所有tag给正则表达式使用
        String regexpTag = Arrays.stream(tags).collect(Collectors.joining("|"));
        Question question = new Question();
        question.setId(queryQuestion.getId());
        question.setTag(regexpTag);

        //查询相关问题
        List<Question> questions = questionExtMapper.selectRelated(question);
        //map：将第一个层级循环出来
        List<QuestionDTO> questionDTOS = questions.stream().map(q -> {
            QuestionDTO questionDTO = new QuestionDTO();
            BeanUtils.copyProperties(q, questionDTO);
            return questionDTO;
        }).collect(Collectors.toList());

        return questionDTOS;
    }
}
